package com.example.demo.util;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.digest.HMac;
import cn.hutool.crypto.digest.HmacAlgorithm;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.json.JSONUtil;
import com.example.demo.pojo.dto.dingtalk.*;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

/**
 * 钉钉工具
 * 文档：https://open.dingtalk.com/document/robots/customize-robot-security-settings
 *
 * @author TongDaShuai
 * @since 2021/12/14
 */
public class DingTalkUtils {

    /**
     * 按钮竖直排列
     */
    public static final String ORIENTATION_VERTICAL = "0";

    /**
     * 按钮横向排列
     */
    public static final String ORIENTATION_HORIZONTAL = "1";


    /**
     * 发送钉钉机器人群通知(不加签)
     *
     * @param msgNotifyReqDto 请求参数
     * @param url 机器人的webhook地址
     * @throws UnsupportedEncodingException
     */
    public static void sendRobotMsg(BaseRobotMsgNotifyReqDto msgNotifyReqDto, String url) throws UnsupportedEncodingException {
        sendRobotMsg(msgNotifyReqDto, false, null, url);
    }


    /**
     * 发送钉钉机器人群通知
     *
     * @param msgNotifyReqDto 请求参数
     * @param doSign 是否加签
     * @param secret 加签密钥
     * @param url 机器人的webhook地址
     * @throws UnsupportedEncodingException
     */
    public static void sendRobotMsg(BaseRobotMsgNotifyReqDto msgNotifyReqDto, boolean doSign, String secret,
                                    String url) throws UnsupportedEncodingException {
        // 加签
        if (doSign) {
            url = signUrl(url, secret);
        }

        System.out.println("钉钉机器人消息通知请求参数：" + JSONUtil.toJsonStr(msgNotifyReqDto));
        // 发送消息通知
        HttpResponse response = HttpRequest.post(url)
                .body(JSONUtil.toJsonStr(msgNotifyReqDto))
                .timeout(10000)
                .execute();
        System.out.println("钉钉机器人消息通知返回response:" + response);
    }



    /**
     * 对请求地址进行加签
     *
     * @param signUrl 设置了加签的机器人webhook地址
     * @param secret 密钥
     * @return
     * @throws UnsupportedEncodingException
     */
    private static String signUrl(String signUrl, String secret) throws UnsupportedEncodingException {
        // 把timestamp+"\n"+密钥当做签名字符串，使用HmacSHA256算法计算签名，然后进行Base64 encode，
        // 最后再把签名参数再进行urlEncode，得到最终的签名（需要使用UTF-8字符集）。
        HMac hMac = SecureUtil.hmacSha256(secret);
        long timestamp = System.currentTimeMillis();
        String stringToSign = timestamp + "\n" + secret;
        String sign = URLEncoder.encode(hMac.digestBase64(stringToSign, false),"UTF-8");
        String url = StrUtil.format("{}&timestamp={}&sign={}", signUrl, timestamp, sign);
        return url;
    }

    /**
     * 对请求地址进行加签
     *
     * @param signUrl 设置了加签的机器人webhook地址
     * @param secret 密钥
     * @return
     * @throws UnsupportedEncodingException
     */
    private static String signUrl2(String signUrl, String secret) throws UnsupportedEncodingException {
        // 把timestamp+"\n"+密钥当做签名字符串，使用HmacSHA256算法计算签名，然后进行Base64 encode，
        // 最后再把签名参数再进行urlEncode，得到最终的签名（需要使用UTF-8字符集）。
        HMac hMac = SecureUtil.hmac(HmacAlgorithm.HmacSHA256, secret);
        HMac hMac2 = SecureUtil.hmacSha256(secret);
        long timestamp = System.currentTimeMillis();
        String stringToSign = timestamp + "\n" + secret;

        String sign = URLEncoder.encode(Base64.encodeStr(hMac.digest(stringToSign), false, false),"UTF-8");
        System.out.println("sign:" + sign);

        String sign2 = URLEncoder.encode(hMac2.digestBase64(stringToSign, false),"UTF-8");
        System.out.println("sign2:" + sign2);

        System.out.println(URLEncoder.encode(Base64.encodeStr(hMac.digest(stringToSign), false, false),"UTF-8"));


        String url = StrUtil.format("{}&timestamp={}&sign={}", signUrl, timestamp, sign);
        return url;
    }



    public static void main(String[] args) throws UnsupportedEncodingException, NoSuchAlgorithmException, InvalidKeyException {

        // 测试加签类型消息通知
        // 关键字请求
        String keywordUrl = "https://oapi.dingtalk.com/robot/send?access_token=25778d01208ef7e09bd45e94f37b1bf0d69ab0ef032569cd0693a4ee35f1425a";
        String signUrl = "https://oapi.dingtalk.com/robot/send?access_token=9ba11fd78cfb605c5ed04644d81ddb14f8869229eb6b6ca9f6b66697b0298a66";
        String secret = "SECb12bf55009b4380c00dd6784a3f91a5e10c32ac25a4949c1b3a99fc5c4101731";
        String markdownText = "#### 3 浏览器访问arthas\n" +
                "\n" +
                "启动arthas然后选择进程后，会有个connnect 127.0.0.1 3658的信息，这个是我们可以通过浏览器访问控制台。\n" +
                "\n" +
                "```cmd\n" +
                "http://127.0.0.1:3658/\n" +
                "```\n" +
                "\n" +
                "![image-20210808204936403](https://i.loli.net/2021/08/08/onYA1fUy2J76uXr.png)";
        // 普通text类型消息通知
//        BaseRobotMsgNotifyReqDto req = TextReqDto.build()
//                .content("tds的text类型告警测试")
//                .atMobile("15755507531");
//        sendRobotMsg(req, true, secret, signUrl);

        // 发送所有人
//        sendRobotMsg(req, keywordUrl);



          // link类型消息通知
//        BaseRobotMsgNotifyReqDto linkReq = LinkReqDto.build()
//                .picUrl("https://img2.baidu.com/it/u=2457670919,3886484878&fm=26&fmt=auto")
//                .messageUrl("https://img0.baidu.com/it/u=1051577226,2771334401&fm=26&fmt=auto")
//                .text("测试link类型消息通知")
//                .title("link通知标题");
//        sendRobotMsg(linkReq, true, secret, signUrl);

//        // markdown类型消息通知
//        BaseRobotMsgNotifyReqDto markdownReq = MarkdownReqDto.build()
//                .title("测试markdown类型消息通知")
//                .text(markdownText)
//                .atMobile("15755507531");
//        sendRobotMsg(markdownReq, true, secret, signUrl);



//        // actionCard类型消息（单链接跳转消息:link+markdown）
//        ActionCardReqDto actionCardReqDto = ActionCardReqDto.build()
//                .title("测试actionCard类型消息通知")
//                .text(markdownText)
//                .btnOrientation(ORIENTATION_VERTICAL)
//                .singleTitle("actionCard标题")
//                .singleURL("https://img0.baidu.com/it/u=1051577226,2771334401&fm=26&fmt=auto");
//        sendRobotMsg(actionCardReqDto, true, secret, signUrl);

        // feedCard类型消息（多链接跳转消息）
        FeedCardReqDto.LinkDto linkDto1 = FeedCardReqDto.LinkDto.build()
                .title("feedCard通知标题")
                .picURL("https://img2.baidu.com/it/u=2457670919,3886484878&fm=26&fmt=auto")
                .messageURL("https://img0.baidu.com/it/u=1051577226,2771334401&fm=26&fmt=auto");
        FeedCardReqDto.LinkDto linkDto2 = FeedCardReqDto.LinkDto.build()
                .title("feedCard通知标题2")
                .picURL("https://img0.baidu.com/it/u=1051577226,2771334401&fm=26&fmt=auto")
                .messageURL("https://img0.baidu.com/it/u=1051577226,2771334401&fm=26&fmt=auto");
        FeedCardReqDto feedCardReq = FeedCardReqDto.build()
                .link(linkDto1)
                .link(linkDto2);
        sendRobotMsg(feedCardReq, true, secret, signUrl);
    }

//    /**
//     * 普通类型的消息通知
//     *
//     * @param atPhone 需要@的人的手机号
//     * @param content 消息内容
//     * @param url 机器人的webhook地址
//     */
//    public static void sendRobotMsg(String atPhone, String content, String url) throws UnsupportedEncodingException {
//        sendRobotMsg(false, null, false, DingMsgTypeEnum.text, atPhone, content, url);
//    }
//
//    /**
//     * 普通类型的消息通知(通知所有人)
//     *
//     * @param content 消息内容
//     * @param url 机器人的webhook地址
//     */
//    public static void sendRobotMsg(String content, String url) throws UnsupportedEncodingException {
//        sendRobotMsg(false, null, true, DingMsgTypeEnum.text, null, content, url);
//    }
//
//    /**
//     * 普通类型的消息通知
//     *
//     * @param doSign 是否加签
//     * @param secret 加签密钥
//     * @param isAtAll 是否@所有人
//     * @param msgType 消息类型，详见DingMsgTypeEnum模具
//     * @param atPhone 需要@的人的手机号
//     * @param content 消息内容
//     * @param url 机器人的webhook地址
//     */
//    public static void sendRobotMsg(boolean doSign, String secret, boolean isAtAll, DingMsgTypeEnum msgType,
//                                    String atPhone, String content, String url) throws UnsupportedEncodingException {
//        // 加签
//        if (doSign) {
//            url = signUrl(url, secret);
//        }
//        DingRobotReqDto req;
//        // 组装请求参数
//        switch (msgType) {
//            case text:
//                req = DingRobotReqDto.build(msgType.name())
//                        .atMobile(atPhone)
//                        .content(content)
//                        .isAtAll(isAtAll);
//                break;
//            case link:
//                req = DingRobotReqDto.build(msgType.name())
//                        .text(atPhone)
//                        .content(content)
//                        .isAtAll(isAtAll);
//                break;
//            default:
//                throw new RuntimeException("暂不支持的钉钉消息类型");
//        }
//        // 发送消息通知
//        HttpResponse response = HttpRequest.post(url)
//                .body(JSONUtil.toJsonStr(req))
//                .timeout(10000)
//                .execute();
//        System.out.println("钉钉机器人消息通知返回response:" + response);
//    }
}
